package com.view.test.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.drawable.ColorDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.view.test.R;
import com.view.test.bean.CoordBean;

import java.util.ArrayList;


public class LineChartView extends View {

    private PopupWindow mPopWin;
    private int meanHeight;
    private int meanWidth;
    private float scrollX;
    private float downX;
    private float downY;
    private float right;
    private float left;
    private float meanVH;
    private int horizontal_color;
    private int horizontal_dotted_color;
    private int vertical_color;


    public LineChartView(Context context) {
        super(context);
    }

    public LineChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LineChartView);
        horizontal_color = typedArray.getColor(R.styleable.LineChartView_horizontal_color, Color.BLUE);
        horizontal_dotted_color = typedArray.getColor(R.styleable.LineChartView_horizontal_dotted_color, Color.GRAY);
        vertical_color = typedArray.getColor(R.styleable.LineChartView_vertical_color, Color.RED);
        typedArray.recycle();
    }

    public LineChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

    }

    private ArrayList<CoordBean> coordBeans = new ArrayList<>();

    private float[] axisDataY;



    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //canva画布
        canvaPath(canvas);

        chartCircle(canvas);
    }

    private int marginLeftRight = 100;
    private int marginTopBottom = 100;
    private int paddingPath = 80;
    private int textSize = 30;
    private int startX;
    private int endX;
    private int startY;
    private int endY;

    private String[] axisDataX;

    private int lineNumY = 6;
    private int lintNumX = 7;

    private float maxValue = 8000;
    private float minValue = -100;

    private float meanValue;


    public void setAxisDataX(String[] axisDataX) {
        this.axisDataX = axisDataX;
    }

    public void setAxisDataY(float[] axisDataY) {
        this.axisDataY = axisDataY;
    }

    public void setMaxValue(float maxValue) {
        this.maxValue = maxValue;
    }

    public void setMinValue(float minValue) {
        this.minValue = minValue;
    }


    private void canvaPath(Canvas canvas) {

        //折线
        Paint brokenLinePaint = brokenLinePaint();
        //文本
        Paint textPaint = textPaint();
        //虚线
        Paint dottedPaint = dottedPaint();
        PathEffect pathEffect = new DashPathEffect(new float[]{5, 5, 5, 5}, 2);
        dottedPaint.setPathEffect(pathEffect);


        //平均高度
        meanHeight = (getHeight() - marginTopBottom * 2) / (lineNumY - 1);
        //平均宽度
        meanWidth = (getWidth() - marginLeftRight * 2) / (lintNumX - 1);

        //平均值
        meanValue = maxValue / (lineNumY - 1);
        //平均值的高度
        meanVH = meanValue / meanHeight;

        //X
        drawLineX(canvas, textPaint, dottedPaint);
        //Y
        drawLineY(canvas, textPaint);
        textPaint.reset();

        //折线点   xy
        drawLineChart(canvas, brokenLinePaint);

        //滑动时出现的线
        if (!action_up){
            scrollViewX(canvas, brokenLinePaint);
        }

        brokenLinePaint.reset();

    }

    private void drawLineChart(Canvas canvas, Paint brokenLinePaint) {
        coordBeans.clear();
        Path pathChart = new Path();
        for (int i = 0; i < lintNumX; i++) {
            if (i == 0) {
                pathChart.moveTo(marginLeftRight, marginTopBottom + ((lineNumY - 1) * meanHeight) - axisDataY[i]);
            }
            pathChart.lineTo(marginLeftRight + meanWidth * i, marginTopBottom + ((lineNumY - 1) * meanHeight) - axisDataY[i] / meanVH);//marginTopBottom + ((lineNumY - 1) * meanHeight) - math[i%6])
            canvas.drawCircle(marginLeftRight + meanWidth * i, marginTopBottom + ((lineNumY - 1) * meanHeight) - axisDataY[i] / meanVH, 3, brokenLinePaint);
            coordBeans.add(new CoordBean(marginLeftRight + meanWidth * i, marginTopBottom + ((lineNumY - 1) * meanHeight) - axisDataY[i] / meanVH, axisDataY[i]));
        }
        canvas.drawPath(pathChart, brokenLinePaint);

    }

    private void drawLineY(Canvas canvas, Paint textPaint) {
        for (int i = 0; i < lintNumX; i++) {
            Path path = new Path();
            path.moveTo(marginLeftRight + (i * meanWidth), meanHeight);
            if (i == 0) {
                startX = marginLeftRight;
                startY = marginTopBottom;
            } else {
                endY = marginTopBottom + ((lineNumY - 1) * meanHeight);
                endX = marginLeftRight + (i * meanWidth);
            }

            path.lineTo(marginLeftRight + (i * meanWidth), meanHeight + ((lineNumY - 1) * meanHeight));
            canvas.drawCircle(marginLeftRight + (i * meanWidth), marginTopBottom + ((lineNumY - 1) * meanHeight), 5, textPaint);
            canvas.drawText(axisDataX[i] + "", marginLeftRight + (i * meanWidth) - 30, marginTopBottom + ((lineNumY - 1) * meanHeight) + meanHeight / 2, textPaint);
        }
    }

    private void drawLineX(Canvas canvas, Paint textPaint, Paint dottedPaint) {

        for (int i = 0; i < lineNumY; i++) {
            if (lineNumY - 1 == i) {
                Paint paint = new Paint();
                Path path = new Path();
                paint.setColor(Color.BLUE);
                paint.setStrokeWidth(3);
                paint.setStyle(Paint.Style.STROKE);
                paint.setAntiAlias(true);
                path.moveTo(marginLeftRight, marginTopBottom + (i * meanHeight));
                path.lineTo(getWidth() - marginLeftRight, marginTopBottom + (i * meanHeight));
                canvas.drawPath(path, paint);
                paint.reset();
            } else {
                Path linePath = new Path();
                linePath.moveTo(marginLeftRight, marginTopBottom + (i * meanHeight));
                linePath.lineTo(getWidth() - marginLeftRight, marginTopBottom + (i * meanHeight));
                canvas.drawPath(linePath, dottedPaint);
            }

            String s = (((lineNumY - 1) - i) * meanValue) + "";
            float method = textPaint.measureText(s);
            canvas.drawText(s, marginLeftRight - method - 10, marginTopBottom + (i * meanHeight) + 10, textPaint);
        }

        dottedPaint.reset();
    }

    private Paint dottedPaint() {
        Paint dottedPaint = new Paint();
        dottedPaint.setAntiAlias(true);
        dottedPaint.setStyle(Paint.Style.STROKE);
        dottedPaint.setStrokeWidth(2);
        dottedPaint.setColor(horizontal_dotted_color);
        return dottedPaint;
    }

    private Paint textPaint() {
        Paint textPaint = new Paint();
        textPaint.setColor(horizontal_color);
        textPaint.setStrokeWidth(3);
        textPaint.setTextSize(30);
        return textPaint;
    }

    private Paint brokenLinePaint() {
        Paint brokenLinePaint = new Paint();
        brokenLinePaint.setColor(vertical_color);
        brokenLinePaint.setStrokeWidth(3);
        brokenLinePaint.setStyle(Paint.Style.STROKE);
        brokenLinePaint.setAntiAlias(true);
        return brokenLinePaint;
    }

    boolean   action_up = true;
    @Override
    public boolean onTouchEvent(MotionEvent event) {


        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                action_up = false;
                for (int i = 0; i < coordBeans.size(); i++) {
                    if (Math.abs(downX - coordBeans.get(i).getCoordX()) < paddingPath / 2
                            && Math.abs(downY - coordBeans.get(i).getCoordY()) < paddingPath / 2) {
                        isClick = true;
                        isClickIndex = i;
                        scrollX = coordBeans.get(i).getCoordX();
                        invalidate();
                        showDetails(isClickIndex);
                        break;
                    }
                }
                return true;
            case MotionEvent.ACTION_MOVE:

                float x = event.getX();
                float y = event.getY();

                action_up = false;
                Log.i("onTouchEvent", x + "---" + y);
                if (x >= startX && x <= endX && y >= startY && y <= endY) {
                    CoordBean coorBean = getCoorBean(x);
                    if (coorBean != null) {
                        invalidate();
                        showDetails(isClickIndex);
                    }
                }

                return true;

            case MotionEvent.ACTION_UP:
                action_up = true;
                invalidate();
                if (mPopWin != null) mPopWin.dismiss();
                return true;
        }


        return super.onTouchEvent(event);
    }

    private CoordBean getCoorBean(float x) {
        CoordBean coordBean = null;
        for (int i = 0; i < coordBeans.size(); i++) {
            if (Math.abs(x - coordBeans.get(i).getCoordX()) <= meanWidth / 2) {
                Log.i("onTouchEvent", "" + Math.abs(x - coordBeans.get(i).getCoordX()));

                if (x < right && x > left) {
                    break;
                }
                right = coordBeans.get(i).getCoordX() + meanWidth / 2;
                left = coordBeans.get(i).getCoordX() - meanWidth / 2;
                coordBean = coordBeans.get(i);
                isClick = true;
                isClickIndex = i;
                scrollX = coordBeans.get(i).getCoordX();
                break;
            }
        }
        return coordBean;
    }

    private boolean isClick;
    private int isClickIndex = -1;

    private void chartCircle(Canvas canvas) {
        Paint paint = new Paint();
        if (!action_up){
            paint.setColor(Color.GREEN);
        }else{
            paint.setColor(Color.RED);
        }

        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setAntiAlias(true);
        if (isClick && isClickIndex > -1) {
            canvas.drawCircle(coordBeans.get(isClickIndex).getCoordX(), coordBeans.get(isClickIndex).getCoordY(), 6, paint);
        }
    }

    private void showDetails(int index) {
        if (mPopWin != null) mPopWin.dismiss();
        TextView tv = new TextView(getContext());
        tv.setTextColor(Color.WHITE);
        tv.setBackgroundColor(Color.RED);
        tv.setPadding(20, 0, 20, 0);
        tv.setGravity(Gravity.CENTER);
        tv.setText(coordBeans.get(index).getClickCoord() + "");
        mPopWin = new PopupWindow(tv, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mPopWin.setBackgroundDrawable(new ColorDrawable(0));
        mPopWin.setFocusable(false);
        // 根据坐标点的位置计算弹窗的展示位置
        int xoff = (int) (coordBeans.get(index).getCoordX() - 0.5 * paddingPath);
        int yoff = (int) (coordBeans.get(index).getCoordY() - paddingPath);
        Log.i("showDetails", coordBeans.get(index).getCoordX() + "---" + coordBeans.get(index).getCoordY());
        mPopWin.showAsDropDown(this, xoff, yoff - getHeight());
        mPopWin.update();
    }
    private void scrollViewX(Canvas canvas, Paint paintPath) {

        if (scrollX > 0) {
            canvas.drawLine(scrollX, startY, scrollX, endY, paintPath);
        }
    }

}

